7 #define MAXDIGITS 10001 /* maximum length bignum */
9 #define PLUS 1 /* positive sign bit */
10 #define MINUS -1 /* negative sign bit */
13 char digits
[MAXDIGITS
]; /* represent the number */
14 int signbit
; /* 1 if positive, -1 if negative */
15 int lastdigit
; /* index of high-order digit */
19 void subtract_bignum(bignum
*a
, bignum
*b
, bignum
*c
);
20 void zero_justify(bignum
*n
);
21 int compare_bignum(bignum
*a
, bignum
*b
);
23 void print_bignum(bignum
*n
)
27 if (n
->signbit
== MINUS
) printf("-");
28 for (i
=n
->lastdigit
; i
>=0; i
--)
29 printf("%c",'0'+ n
->digits
[i
]);
34 void int_to_bignum(int s
, bignum
*n
)
37 int t
; /* int to work with */
39 if (s
>= 0) n
->signbit
= PLUS
;
40 else n
->signbit
= MINUS
;
42 for (i
=0; i
<MAXDIGITS
; i
++) n
->digits
[i
] = (char) 0;
50 n
->digits
[ n
->lastdigit
] = (t
% 10);
54 if (s
== 0) n
->lastdigit
= 0;
57 void string_to_bignum(const string
&s
, bignum
*n
)
66 if (s
[0] != '-') n
->signbit
= PLUS
;
67 else n
->signbit
= MINUS
;
69 for (i
=0; i
<MAXDIGITS
; i
++) n
->digits
[i
] = (char) 0;
74 for (i
=0; i
<len
; ++i
){
76 n
->digits
[n
->lastdigit
] = s
[i
] - '0';
81 void initialize_bignum(bignum
*n
)
89 if (a
> b
) return(a
); else return(b
);
94 void add_bignum(bignum
*a
, bignum
*b
, bignum
*c
)
96 int carry
; /* carry digit */
101 if (a
->signbit
== b
->signbit
) c
->signbit
= a
->signbit
;
103 if (a
->signbit
== MINUS
) {
105 subtract_bignum(b
,a
,c
);
109 subtract_bignum(a
,b
,c
);
115 c
->lastdigit
= max(a
->lastdigit
,b
->lastdigit
)+1;
118 for (i
=0; i
<=(c
->lastdigit
); i
++) {
119 c
->digits
[i
] = (char) (carry
+a
->digits
[i
]+b
->digits
[i
]) % 10;
120 carry
= (carry
+ a
->digits
[i
] + b
->digits
[i
]) / 10;
127 void subtract_bignum(bignum
*a
, bignum
*b
, bignum
*c
)
129 int borrow
; /* has anything been borrowed? */
130 int v
; /* placeholder digit */
133 initialize_bignum(c
);
135 if ((a
->signbit
== MINUS
) || (b
->signbit
== MINUS
)) {
136 b
->signbit
= -1 * b
->signbit
;
138 b
->signbit
= -1 * b
->signbit
;
142 if (compare_bignum(a
,b
) == PLUS
) {
143 subtract_bignum(b
,a
,c
);
148 c
->lastdigit
= max(a
->lastdigit
,b
->lastdigit
);
151 for (i
=0; i
<=(c
->lastdigit
); i
++) {
152 v
= (a
->digits
[i
] - borrow
- b
->digits
[i
]);
153 if (a
->digits
[i
] > 0)
160 c
->digits
[i
] = (char) v
% 10;
166 int compare_bignum(bignum
*a
, bignum
*b
)
170 if ((a
->signbit
== MINUS
) && (b
->signbit
== PLUS
)) return(PLUS
);
171 if ((a
->signbit
== PLUS
) && (b
->signbit
== MINUS
)) return(MINUS
);
173 if (b
->lastdigit
> a
->lastdigit
) return (PLUS
* a
->signbit
);
174 if (a
->lastdigit
> b
->lastdigit
) return (MINUS
* a
->signbit
);
176 for (i
= a
->lastdigit
; i
>=0; i
--) {
177 if (a
->digits
[i
] > b
->digits
[i
]) return(MINUS
* a
->signbit
);
178 if (b
->digits
[i
] > a
->digits
[i
]) return(PLUS
* a
->signbit
);
184 void zero_justify(bignum
*n
)
186 while ((n
->lastdigit
> 0) && (n
->digits
[ n
->lastdigit
] == 0))
189 if ((n
->lastdigit
== 0) && (n
->digits
[0] == 0))
190 n
->signbit
= PLUS
; /* hack to avoid -0 */
194 void digit_shift(bignum
*n
, int d
) /* multiply n by 10^d */
198 if ((n
->lastdigit
== 0) && (n
->digits
[0] == 0)) return;
200 for (i
=n
->lastdigit
; i
>=0; i
--)
201 n
->digits
[i
+d
] = n
->digits
[i
];
203 for (i
=0; i
<d
; i
++) n
->digits
[i
] = 0;
205 n
->lastdigit
= n
->lastdigit
+ d
;
210 void multiply_bignum(bignum
*a
, bignum
*b
, bignum
*c
)
212 bignum row
; /* represent shifted row */
213 bignum tmp
; /* placeholder bignum */
214 int i
,j
; /* counters */
216 initialize_bignum(c
);
220 for (i
=0; i
<=b
->lastdigit
; i
++) {
221 for (j
=1; j
<=b
->digits
[i
]; j
++) {
222 add_bignum(c
,&row
,&tmp
);
228 c
->signbit
= a
->signbit
* b
->signbit
;
234 void divide_bignum(bignum
*a
, bignum
*b
, bignum
*c
)
236 bignum row
; /* represent shifted row */
237 bignum tmp
; /* placeholder bignum */
238 int asign
, bsign
; /* temporary signs */
239 int i
,j
; /* counters */
241 initialize_bignum(c
);
243 c
->signbit
= a
->signbit
* b
->signbit
;
251 initialize_bignum(&row
);
252 initialize_bignum(&tmp
);
254 c
->lastdigit
= a
->lastdigit
;
256 for (i
=a
->lastdigit
; i
>=0; i
--) {
258 row
.digits
[0] = a
->digits
[i
];
260 while (compare_bignum(&row
,b
) != PLUS
) {
262 subtract_bignum(&row
,b
,&tmp
);
282 reverse(a
.begin(), a
.end());
283 reverse(b
.begin(), b
.end());
285 string_to_bignum(a
, &n1
);
286 string_to_bignum(b
, &n2
);
287 subtract_bignum(&n1
, &n2
, &n3
);